<?php
declare(strict_types=1);

namespace App\Controller;

use App\Constants\ErrorCode;
use App\Constants\Action;
use Exception;
use Hyperf\Contract\OnCloseInterface;
use Hyperf\Contract\OnMessageInterface;
use Hyperf\Contract\OnOpenInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class WebSocketController implements OnMessageInterface, OnOpenInterface, OnCloseInterface
{

    /**
     * 客户端发来消息
     * @param $server
     * @param $frame
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function onMessage($server, $frame): void
    {
        try {
            // 开启日志记录
            logger()->info('请求日志', ['fd' => $frame->fd, 'data' => $frame->data]);
            $this->sendOne($frame->fd, $server, Action::SUCCESS, msg: '暂服处理');
            $this->sendOneErr($frame->fd, $server, Action::ERR, msg: '暂服处理');
            //TODO
        } catch (Exception $e) {
            $this->sendOneErr($frame->fd, $server, Action::PARAM_ERR, msg: $e->getMessage());
            return;
        }
    }

    /**
     * 客户端关闭
     * @param $server
     * @param int $fd
     * @param int $reactorId
     * @return void
     */
    public function onClose($server, int $fd, int $reactorId): void
    {
        echo "$fd 客户端关闭\n";
    }

    /**
     * 客户端连接时
     * @param $server
     * @param $request
     * @return void
     */
    public function onOpen($server, $request): void
    {
        echo "$request->fd 客户端连接: 欢迎...\n";
    }

    /**
     * 给单人发送信息,错误
     * @param $client_id
     * @param $server
     * @param $const
     * @param int $code
     * @param string $msg
     * @param array $data
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function sendOneErr($client_id, $server, $const, int $code = ErrorCode::ERR, string $msg = '', array $data = []): void
    {
        $this->sendOne($client_id, $server, $const, $data, $code, $msg);
    }

    /**
     * 给单人发送信息
     * @param $client_id
     * @param $server
     * @param $const
     * @param array $data
     * @param int $code
     * @param string $msg
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function sendOne($client_id, $server, $const, array $data = [], int $code = ErrorCode::SUCCESS, string $msg = ''): void
    {
        try {
            $server->push((int)$client_id, json_res($data, $const, $code, $msg));
        } catch (Exception $e) {
            logger()->info('发送到客户端错误:', ['msg' => $e->getMessage(), 'client_id' => $client_id]);
        }
        //日志
        logger()->info('响应日志:' . json_e(['client_id' => $client_id, 'const' => $const, 'data' => $data, 'msg' => ErrorCode::getMessage($code), 'code' => $code]));
    }
}
